function [S] = fp_adder(A,B,sm)
    % -- Mantissa alignment
    D = abs_diff(A(2:9),B(2:9));
    
    % A_m < B_m
    A_sgn = A(1);
    B_sgn = B(1);
    diff_sgn = xor(A_sgn,B_sgn);
    sm = xor(sm,diff_sgn);
    sgn = xor(B_sgn,sm);
    A_largest = binint2dec(A(2:9))>=binint2dec(B(2:9));
    if(A_largest)
        t = A;
        A = B;
        B = t;
    end
    if(sm && ~A_largest)
        sgn = ~sgn;
    end
    
    % Shift A right as much as the exponents differ and put A together
    A_m = shift_r([1 A(10:32)],D(4:8));
    
    % -- Add mantissas
    A_m = [0 A_m];  
    B_m = zeros(1,length(A_m));
    B_m(2) = 1;
    B_m(3:25) = B(10:32);
    
    ci = sm;
    for i = length(A_m):-1:1,
        a = A_m(i);
        b = B_m(i);
        [s,ci] = FA(b,xor(a,sm),ci);
        M(i) = s;
    end
      
    % -- Renormalization of the mantissa of the sum
    A_e = B(2:9);
    if(M(1))
       % 1x.xx...
       M = [0 M];
       A_e = add(A_e,[zeros(1,7) 1]);
    else
        % 0x.xx...
        for i = 2:length(M),
           if M(i)
               break;
           end
        end
        M = [M(i-1:end) zeros(1,i-2)];
        
        if i > 1
            for j = 1:i-2,
                A_e = sub(A_e,[zeros(1,7) 1]);
            end
        end
    end
    
    % -- Rounding of sum
    % round to zero
    M = M(3:25);   
    S = [sgn A_e M];
end

function b = bin_to_dec(B)
    len_b = length(B);
    b = 0;
    for i = 1:len_b,
        b = b + B(len_b-i+1)*2^(i-1);
    end
end

function [s,co] = FA(a,b,ci)
    t = xor(a,b);
    s = xor(t,ci); 
    co = (a&&b)||(t&&ci);
end

function Z = shift_r(B,ED)
    P5 = [B 0 0];
    if ED(1) == 0
        P4 = P5;
    else
        P4 = [zeros(1,16) P5(1:10)];
    end

    if ED(2) == 0
        P3 = P4;
    else
        P3 = [zeros(1,8) P4(1:18)];
    end

    if ED(3) == 0
        P2 = P3;
    else
        P2 = [zeros(1,4) P3(1:22)];
    end

    if ED(4) == 0
        P1 = P2;
    else
        P1 = [zeros(1,2) P2(1:24)];
    end
    
    if ED(5) == 0
        P0 = P1;
    else
        P0 = [0 P1(1:25)];
    end
    
    sticky = ((P5(11)|P5(12)|P5(13)|P5(14)|P5(15)|P5(16)|P5(17)|P5(18)|P5(19)|P5(20)|P5(21)|P5(22)|P5(23)|P5(24)|P5(25)|P5(26))&ED(1)) | ((P4(19)|P4(20)|P4(21)|P4(22)|P4(23)|P4(24)|P4(25)|P4(26))&ED(2)) | ((P3(23)|P3(24)|P3(25)|P3(26))&ED(3)) | ((P2(25)|P2(26))&ED(4)) | (P1(26)&ED(5));
    Z = [P0 sticky];
end

function D = abs_diff(A,B)
    B_e_largest = (bi2de(B,'left-msb') > bi2de(A,'left-msb'));
    if(B_e_largest)
        t = A;
        A = B;
        B = t;
    end
    
    % Diff in exponent
    len = length(B);
    D = zeros(1,len); % exponent diff
    ci = 1; % do subtraction
    for i = len:-1:1,
        a = A(i);
        b = B(i);
        [s,ci] = FA(a,xor(b,1),ci);
        D(i) = s;
    end
end

function [Z,co] = add(A,B)
    len = length(A);
    Z = zeros(1,len);
    ci = 0;
    for i = len:-1:1,
        a = A(i);
        b = B(i);
        [s,ci] = FA(a,b,ci);
        Z(i) = s;
    end
    co = ci;
end

function [Z,co] = sub(A,B)
    len = length(A);
    Z = zeros(1,len);
    ci = 1;
    for i = len:-1:1,
        a = A(i);
        b = B(i);
        [s,ci] = FA(a,xor(b,1),ci);
        Z(i) = s;
    end
    co = ci;
end

function [t] = binfrac2dec(T)
    len_t = length(T);
    t = 0;
    for i = 1:len_t,
        t = t + T(i)*2^-(i);
    end 
end

function [t] = binint2dec(T)
    len_t = length(T);
    t = 0;
    for i = len_t:-1:1,
        t = t + T(i)*2^(len_t-i);
    end 
end


function []=prnt(B)
    for i=1:length(B),
        if i == 2 || i == 10 || i == 33
            fprintf(' '); 
        end
        fprintf('%d',B(i)); 
    end
    fprintf('\n');
end

function []=prnt_mantissa(B, h)
    for i=1:length(B),
        if (h == 1 && i == 2) || (h == 2 && i == 3) || (h == 0 && i == 24) || (h == 1 && i == 25) || (h == 2 && i == 26)
            fprintf(' '); 
        end
        fprintf('%d',B(i)); 
    end
    fprintf('\n');
end
